package com.ljc.service;

import com.ljc.constant.UserConstant;
import com.ljc.entity.FollowingGroup;
import com.ljc.entity.User;
import com.ljc.entity.UserFollowing;
import com.ljc.entity.UserInfo;
import com.ljc.exception.ConditionException;
import com.ljc.interfaces.FollowingGroupApi;
import com.ljc.interfaces.UserApi;
import com.ljc.interfaces.UserFollowingApi;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserFollowingService {
    @DubboReference
    private UserFollowingApi userFollowingApi;
    @DubboReference
    private FollowingGroupApi followingGroupApi;
    @DubboReference
    private UserApi userApi;

    /**
     * 添加用户关注
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addUserFollowings(UserFollowing userFollowing) {
        // 获取这个用户的分组id
        Long groupId = userFollowing.getGroupId();
        // 如果没有分组，则添加到默认分组
        if (groupId == null) {
            // 查询出默认分组在数据中的id
            FollowingGroup followingGroup = followingGroupApi.getByType(UserConstant.USER_FOLLOWING_GROUP_TYPE_DEFAULT);
            // 将分组id赋值给记录关注关系的实体
            userFollowing.setGroupId(followingGroup.getId());
        } else {
            // 用户选择了分组，获取这个分组的信息
            FollowingGroup followingGroup = followingGroupApi.getById(groupId);
            if (followingGroup == null) {
                throw new ConditionException("关注分组不存在！");
            }
        }
        // 获取要关注的用户的 id
        Long followingId = userFollowing.getFollowingId();
        User dbUser = userApi.getUserById(followingId);
        if (dbUser == null) {
            throw new ConditionException("关注的用户不存在！");
        }
        // 删除之前和该用户的关系
        userFollowingApi.deleteUserFollowing(userFollowing.getUserId(), followingId);
        // 新建和该用户的关注关系
        userFollowing.setCreateTime(new Date());
        userFollowingApi.addUserFollowing(userFollowing);
    }

    /**
     * 根据id 获取用户的关注列表（其中包括不同的关注类型，都要分别返回）
     */
    public List<FollowingGroup> getUserFollowings(Long userId) {
        // 1、获取该用户关注的用户列表
        List<UserFollowing> list = userFollowingApi.getUserFollowings(userId);
        // 2、根据关注用户的id查询关注用户的基本信息
        // 取出其中的 被关注的用户id
        Set<Long> followingIdSet = list.stream().map(UserFollowing::getFollowingId).collect(Collectors.toSet());
        // 查询出被关注人用户的信息，存到userInfoList中
        List<UserInfo> userInfoList = new ArrayList<>();
        if (followingIdSet.size() > 0) {
            userInfoList = userApi.getUserInfoByUserIdS(followingIdSet);
        }
        // 将被关注用户的信息填充到关注关系实体 UserFollowing 中
        for (UserFollowing userFollowing : list) {
            for (UserInfo userInfo : userInfoList) {
                if (userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userFollowing.setUserInfo(userInfo);
                }
            }
        }
        // 3、将关注用户按关注分组进行分类
        // 将当前用户 所有的关注 分组都查询出来
        List<FollowingGroup> groupList = followingGroupApi.getByUserId(userId);
        // 创建一个所有分组的变量 allGroup
        FollowingGroup allGroup = new FollowingGroup();
        allGroup.setName(UserConstant.USER_FOLLOWING_GROUP_ALL_NAME);
        allGroup.setFollowingUserInfoList(userInfoList);
        // 创建返回结果集合，将所有关注、每个分组 的用户信息进行封装
        ArrayList<FollowingGroup> result = new ArrayList<>();
        result.add(allGroup);
        // 遍历 每个关注分组
        for (FollowingGroup followingGroup : groupList) {
            ArrayList<UserInfo> curGroupUserInfoList = new ArrayList<>();
            // 所有关注对象
            for (UserFollowing userFollowing : list) {
                // 如果该关注对象的 分组id 等于当前分组id，则将其信息加入 保存每个分组所有用户信息的集合 中
                if (userFollowing.getGroupId().equals(followingGroup.getId())) {
                    curGroupUserInfoList.add(userFollowing.getUserInfo());
                }
            }
            followingGroup.setFollowingUserInfoList(curGroupUserInfoList);
            result.add(followingGroup);
        }
        return result;
    }

    /**
     * 获取用户粉丝列表
     */
    public List<UserFollowing> getUserFans(Long userId) {
        // 1、获取当前用户的粉丝列表
        List<UserFollowing> fanList = userFollowingApi.getUserFans(userId);
        Set<Long> fanIdSet = fanList.stream().map(UserFollowing::getUserId).collect(Collectors.toSet());
        // 2、根据粉丝的用户id查询基本信息
        // 如果粉丝数大于0，则从数据库中查询粉丝信息
        List<UserInfo> userInfoList = new ArrayList<>();
        if (fanIdSet.size() > 0) {
            userInfoList = userApi.getUserInfoByUserIdS(fanIdSet);
        }
        // 3、查询当前用户是否已经关注该粉丝
        // 查询当前用户的关注关系，看看当前用户的粉丝是否被当前用户关注
        List<UserFollowing> followingList = userFollowingApi.getUserFollowings(userId);
        for (UserFollowing fan : fanList) {
            for (UserInfo userInfo : userInfoList) {
                // 初始化单向关注状态
                if (fan.getUserId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(false);
                    fan.setUserInfo(userInfo);
                }
            }
            // 判断是否双向关注，设置双相关注状态
            for (UserFollowing userFollowing : followingList) {
                if (userFollowing.getFollowingId().equals(fan.getUserId())) {
                    fan.getUserInfo().setFollowed(true);
                }
            }
        }
        return fanList;
    }

    /**
     * 新建用户关注分组
     */
    public Long addUserFollowingGroups(FollowingGroup followingGroup) {
        followingGroup.setCreateTime(new Date());
        followingGroup.setType(UserConstant.USER_FOLLOWING_GROUP_TYPE_USER);
        followingGroup = followingGroupApi.addFollowingGroup(followingGroup);
        return followingGroup.getId();
    }

    /**
     * 获取用户关注分组
     */
    public List<FollowingGroup> getUserFollowingGroups(Long userId) {
        return followingGroupApi.getUserFollowingGroups(userId);
    }

    /**
     * 检查查询到的用户和当前用户的关注状态
     */
    public List<UserInfo> checkFollowingStatus(List<UserInfo> userInfoList, Long userId) {
        List<UserFollowing> userFollowingList = userFollowingApi.getUserFollowings(userId);
        for (UserInfo userInfo : userInfoList) {
            userInfo.setFollowed(false);
            for (UserFollowing userFollowing : userFollowingList) {
                // 如果当前用户的关注用户的id和查询到的用户的id重合，在userInfo中设置关注关系并返回
                if (userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(true);
                }
            }
        }
        return userInfoList;
    }
}
